home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 25
/
CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso
/
CUCD
/
WWW
/
http
/
www.cu-amiga.co.uk
/
features
/
c-tutorial
/
Part-13.lzx
/
Part-13
/
setf2.c
< prev
Wrap
C/C++ Source or Header
|
2003-02-01
|
7KB
|
277 lines
#include<exec/libraries.h>
#include<exec/memory.h>
#include<graphics/text.h>
#include<intuition/intuition.h>
#include<intuition/screens.h>
#include<libraries/gadtools.h>
#include<utility/tagitem.h>
#include<string.h>
#include<stdio.h>
/* The following few includes assume the PatchLibV6.lha archive */
/* has been unarchived to the same directory as this project */
#include "patchlib/include/patch.h"
#include "patchlib/include/patchtags.h"
#include "patchlib/include/clib/patch_protos.h"
#include<clib/alib_protos.h>
#include<clib/exec_protos.h>
#include<clib/gadtools_protos.h>
#include<clib/intuition_protos.h>
/* The library base global variables */
struct Library* IntuitionBase;
struct Library* GadToolsBase;
struct Library* PatchBase;
/* Need to give prototypes for our functions */
void handleIDCMP(struct Window*);
void setupWindow();
void createWindow(struct Gadget*);
#define MYFONTSIZE (8)
/* Some constants for the size of the window */
#define MYWIN_WIDTH (410)
#define MYWIN_HEIGHT (210)
/* Some constants for the position and size of our gadget */
#define MYGAD_LEFT (10)
#define MYGAD_TOP (10+MYFONTSIZE)
#define MYGAD_WIDTH (MYWIN_WIDTH-MYGAD_LEFT*2)
#define MYGAD_HEIGHT (MYWIN_HEIGHT-MYGAD_TOP*2+MYFONTSIZE)
#define MYGAD_TEXT ("Result Task Library ")
#define MYGAD_ID (0)
/* Initialised structure declaration: describes standard Topaz font */
static struct TextAttr topazFont = { "topaz.font", MYFONTSIZE, 0, 0, };
static struct Window* win;
static struct Gadget* listgad;
static struct List mylist;
static struct SignalSemaphore ready;
/* The library offset of the OpenLibrary() call */
/* (See <pragmas/exec_pragmas.h> for LVOs) */
#define LVO_OPENLIBRARY (-0x228)
void addNode(char* name, struct Library* lib)
{
struct Node* node = AllocVec(sizeof(struct Node), MEMF_PUBLIC | MEMF_CLEAR);
if(node && name)
{
struct Task* task = FindTask(NULL);
char* taskname = task->tc_Node.ln_Name;
int size = strlen(taskname);
if(size < 20)
size = 20;
size += 10+1+strlen(name)+1;
if(node->ln_Name = AllocVec(size, MEMF_PUBLIC))
sprintf(node->ln_Name, "$%08lx %-20s %s", lib, taskname, name);
GT_SetGadgetAttrs(listgad, win, NULL, GTLV_Labels, ~0, TAG_DONE);
AddHead(&mylist, node);
GT_SetGadgetAttrs(listgad, win, NULL, GTLV_Labels, &mylist, TAG_DONE);
}
}
void freeNode(struct Node* node)
{
FreeVec(node->ln_Name);
FreeVec(node);
}
void freeList()
{
struct Node* work;
struct Node* next = mylist.lh_Head;
while(next->ln_Succ)
{
work = next;
next = next->ln_Succ;
freeNode(work);
}
}
#define USEXRES
#ifdef USEXRES
struct PatchXResult* __saveds newf(register __a1 STRPTR name,
register __d0 struct Library* result)
{
struct PatchXResult *xresult;
if (xresult = (struct PatchXResult*)PatchAlloc(PS_TYPE_XRESULT))
{
if(AttemptSemaphore(&ready))
{
addNode(name, result);
ReleaseSemaphore(&ready);
}
xresult->pxr_RegPattern = PATREG_D0;
xresult->pxr_RegD0 = (ULONG)result;
}
return xresult;
}
#else
struct Library* __saveds newf(register __a1 STRPTR name,
register __d0 struct Library* result)
{
if(AttemptSemaphore(&ready))
{
addNode(name, result);
ReleaseSemaphore(&ready);
}
return result;
}
#endif
/* The start of the program */
void main()
{
/* Open libraries... */
if(IntuitionBase = OpenLibrary("intuition.library",37))
{
if(GadToolsBase = OpenLibrary("gadtools.library",37))
{
if(PatchBase = OpenLibrary("patch.library",5))
{
struct Patch* patch;
/* Set up our semaphore and lock it */
InitSemaphore(&ready);
ObtainSemaphore(&ready);
patch = InstallPatchTags((APTR)&newf, LVO_OPENLIBRARY,
PATT_LibraryName, "exec.library",
PATT_PatchName, "MyOLPatch",
PATT_Priority, -5,
PATT_StackSize, 1500,
#ifdef USEXRES
PATT_UseXResult, TRUE,
#endif
TAG_DONE);
/* Now do the real work */
setupWindow();
RemovePatchTags(patch, PATT_TimeOut, 800, TAG_DONE);
CloseLibrary(PatchBase);
}
else
printf("Error: could not open patch.library V5+\n");
CloseLibrary(GadToolsBase);
}
else
printf("Error: could not open gadtools.library\n");
CloseLibrary(IntuitionBase);
}
else
printf("Error: could not open intuition.library\n");
}
/* Setup the window -- do the GadTools stuff */
void setupWindow()
{
struct Screen* scr;
/* We'll copy the visual information for the default public screen */
/* (usually, this is the Workbench screen) */
if(scr = LockPubScreen(NULL))
{
APTR vinfo;
/* Get the visual info so GadTools can render the gadgets nicely */
if(vinfo = GetVisualInfo(scr, TAG_DONE))
{
struct Gadget* glist = NULL;
if(listgad = CreateContext(&glist))
{
struct NewGadget newgad;
/* The offsets of our window borders */
int offleft = scr->WBorLeft;
int offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
/* Setup our first gadget */
newgad.ng_TextAttr = &topazFont;
newgad.ng_VisualInfo = vinfo;
newgad.ng_LeftEdge = MYGAD_LEFT + offleft;
newgad.ng_TopEdge = MYGAD_TOP + offtop;
newgad.ng_Width = MYGAD_WIDTH;
newgad.ng_Height = MYGAD_HEIGHT;
newgad.ng_GadgetText = MYGAD_TEXT;
newgad.ng_GadgetID = MYGAD_ID;
newgad.ng_Flags = 0;
NewList(&mylist);
/* Now create it and add it to our list */
if(listgad = CreateGadget(LISTVIEW_KIND, listgad, &newgad,
GTLV_Labels, &mylist,
TAG_DONE))
createWindow(glist);
else
printf("Error: could not create gadget(s)\n");
/* Free the gadget */
FreeGadgets(glist);
freeList();
}
else
printf("Error: could not create GadTools context\n");
FreeVisualInfo(vinfo);
}
else
printf("Error: could not get visual info\n");
UnlockPubScreen(NULL, scr);
}
else
printf("Error: could not lock public screen\n");
}
/* Actually open the window, in the normal way */
void createWindow(struct Gadget* glist)
{
/* Open our window */
if(win = OpenWindowTags(NULL,
WA_InnerWidth, MYWIN_WIDTH,
WA_InnerHeight, MYWIN_HEIGHT,
WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW,
WA_Gadgets, glist,
TAG_DONE, 0))
{
/* Let GadTools refresh its bits of the window */
GT_RefreshWindow(win, NULL);
/* Now handle messages */
handleIDCMP(win);
CloseWindow(win);
}
else
printf("Error: could not open window\n");
}
/* Our message handling code */
void handleIDCMP(struct Window* win)
{
int going = TRUE;
/* Let the patch work */
ReleaseSemaphore(&ready);
while(going)
{
struct IntuiMessage* intuimsg;
/* Wait for messages to arrive */
WaitPort(win->UserPort);
/* Messages have arrived: loop through all of them */
while(intuimsg = GT_GetIMsg(win->UserPort))
{
/* Act on this message... */
switch(intuimsg->Class)
{
case IDCMP_CLOSEWINDOW:
going = FALSE;
break;
case IDCMP_REFRESHWINDOW:
/* You *MUST* remember to ask for and handle these refresh messages */
GT_BeginRefresh(win);
GT_EndRefresh(win, TRUE);
break;
}
/* Reply when finished with message */
GT_ReplyIMsg(intuimsg);
}
}
/* Stop the patched function working */
ObtainSemaphore(&ready);
}